package socket;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.CompositeByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.util.CharsetUtil;

import socket.utils.AuthModel;
import socket.utils.ByteUtil;
import socket.utils.Constants;
import socket.utils.ResponseSocketUtil;

import javax.xml.bind.DatatypeConverter;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpResponseStatus.valueOf;

public class SimpleServerHandler extends ChannelInboundHandlerAdapter {

    static int count = 0;
     //存放蓝牙Channel
     static Map<String, Channel> channelMap = new HashMap<String, Channel>();
    //存放平台Channel
    static Map<String, Channel> channelMap2 = new HashMap<String, Channel>();
    static String ID = "";

    private WebSocketServerHandshaker handshaker;
    private static final String WEB_SOCKET_URL = "ws://localhost:8888/websocket";

    static byte[] result1;
    ByteBuf resultX = Unpooled.buffer(100);





    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
           //1.定义每个通道
           Channel channel = ctx.channel();
           ByteBuf result = null;
           String end = null;
           String arr = null;
           String id = "";
           if(!(msg instanceof FullHttpRequest)){
               result = (ByteBuf) msg;
               arr = result.toString(CharsetUtil.UTF_8);
               if(result.readableBytes() == 20){
                   if(resultX.readableBytes() == 0){  //第一包数据
                       resultX = result;
                   }else {                            //分包后的第二包
                       resultX.writeBytes(result);
                   }
                   return;
               }else if(result.readableBytes() == 19){
                   resultX.writeBytes(result);
                   result = resultX;
               }else if(result.readableBytes() == 40){
                   resultX = result;
                   return;
               }
               else if(result.readableBytes() == 7){
                   resultX.writeBytes(result);
                   result = resultX;
               }
               else if(result.readableBytes() == 27){
                   resultX.writeBytes(result);
                   result = resultX;
               }
               end = arr.substring(arr.length()-1);
               String begin = arr.substring(0);

           }

           if("]".equals(end)){
               System.out.println("----------蓝牙控制器--------------");
               //--------2.提取控制器ID BEGIN---------
               String [] stringArr= arr.split(",");
               System.out.println("ARR:" + arr);
               String regEx="[^0-9]";
               Pattern p = Pattern.compile(regEx);
               Matcher m = p.matcher(stringArr[1]);
               id = m.replaceAll("").trim();
               System.out.println("ID:" + id);
               //3.添加channel到channelMap中
               channelMap.put(id,channel);
//               NettyConfig.group.add(ctx.channel());
//               Channel hanne=  NettyConfig.group.find(channel.id());
               //--------提取控制器ID END---------

               byte[] result1 = new byte[result.readableBytes()];
               // msg中存储的是ByteBuf类型的数据，把数据读取到byte[]中
               result.readBytes(result1);
               String resultStr = new String(result1);
               // 接收并打印客户端的信息
               System.out.println("Client said:" + ResponseSocketUtil.V(ByteUtil.bytesToHex(result1))+id);
               System.out.println("MAP:" + channelMap.keySet());
               // 释放资源，这行很关键
               result.release();
           }
           //*-------------平台请求-------------*//
           else if(msg instanceof FullHttpRequest){
                //1.给蓝牙控制器发送消息
//                  String responsetest = "FAFB0D0002FFF0";
                  String responsetest = "FAFB04000A839D24781034EA49FCBE";
                   String response = ((FullHttpRequest) msg).getUri();
//                   System.out.println(response);
                   ID = response.substring(response.length()-5);
                   response = response.substring(2,response.length()-5);
//                   System.out.println("jjjjjj"+response);
                   // 在当前场景下，发送的数据必须转换成ByteBuf数组
                   ByteBuf encoded = ctx.alloc().buffer(4 * ByteUtil.hexToBytes(response).length);
                   encoded.writeBytes(ByteUtil.hexToBytes(response));


                   channelMap.get(ID).writeAndFlush(encoded);
                   channelMap2.put(ID,channel);
//                   Thread.sleep(3000);

           }else {

               // msg中存储的是ByteBuf类型的数据，把数据读取到byte[]中
               result1 = new byte[result.readableBytes()];
               result.readBytes(result1);
               String put = ResponseSocketUtil.V(ByteUtil.bytesToHex(result1));
               // 接收并打印客户端的信息
               System.out.println("Client said--------------:" + ResponseSocketUtil.V(ByteUtil.bytesToHex(result1)));
               if(put.contains("日志")){
                   int indexUser= put.indexOf("用户编号");
                   if(indexUser>-1){
                       String userId= put.substring(indexUser+5,indexUser+13);
                       String[] stringArr = userId.split("");
                       StringBuffer sb = new StringBuffer();
                       for(int i = 0;i<userId.length();i+=2){
                           sb.append(stringArr[i+1]);
                       }
                       int indexLock= put.indexOf("门锁识别号");
                       String lockNum= put.substring(indexLock+6,indexLock+38);

                       int indexLogNum= put.indexOf("日志编号");
                       String logNum= put.substring(indexLogNum+5,indexLogNum+13);

                       int indexLockTime= put.indexOf("当前时间");
                       String LockTime= put.substring(indexLockTime+5,indexLockTime+19);

                       SimpleDateFormat formatter1=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                       SimpleDateFormat formatter2=new SimpleDateFormat("yyyyMMddHHmmss");
                       try {
                           LockTime=formatter1.format(formatter2.parse(LockTime));
                       } catch (ParseException e) {
                           e.printStackTrace();
                       }

                       String lockName = select(lockNum);
                       int t = insert(sb.toString(),LockTime,lockNum,logNum,LockTime,lockName);
                       System.out.println(t);

                   }else{
                      return;
                   }
                   return;
               }
               //*--------返回平台数据----------*//*
               handHttpRequest(ctx,  put);
//               handHttpRequest(ctx);
               // 释放资源，这行很关键
               result.release();
           }

    }


    private synchronized void handHttpRequest(ChannelHandlerContext ctx,String msg){
            sendHttpResponse(ctx,msg, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
            return;
    }

    private synchronized void sendHttpResponse(ChannelHandlerContext ctx,String msg, DefaultFullHttpResponse res){
        if (res.getStatus().code() != 200) {
            res.setStatus(OK);
            ByteBuf buf = Unpooled.copiedBuffer(msg.toString(), CharsetUtil.UTF_8);
            res.content().writeBytes(buf);
            buf.release();
        }
        /*try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        //服务端向客户端发送数据
        System.out.println("hhhh"+ctx.channel());
        ChannelFuture f = channelMap2.get(ID).writeAndFlush(res);
        channelMap2.get(ID).close();
        if (res.getStatus().code() == 200) {
            f.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 当出现异常就关闭连接
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
//        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

    protected void handleAllIdle(ChannelHandlerContext ctx) {
        ctx.channel().writeAndFlush("1" + "\r\n");
    }

    private static Connection getConn() throws Exception{
        String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://192.168.3.191:3306/adminabl?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "123456";
        Connection conn = null;
        try {
            Class.forName(driver); //classLoader,加载对应驱动
            conn = (Connection) DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
    private int insert(String userId,String openTime,String lockNum,String logNum,String createTime,String lockName) throws Exception{
        System.out.println("用户ID"+userId);
        Connection conn = getConn();
        int i = 0;
        String sql = "insert into t_open_log (userId,openTime,lockNum,logNum,createTime,lockName) values(?,?,?,?,?,?)";
        PreparedStatement pstmt;
        try {
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1, userId);
            pstmt.setString(2, openTime);
            pstmt.setString(3, lockNum);
            pstmt.setString(4, logNum);
            pstmt.setString(5, createTime);
            pstmt.setString(6, lockName);
            i = pstmt.executeUpdate();
            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }
    private String select(String lockNum) throws Exception{
        Connection conn = getConn();
        String regex = "(.{4})";
        lockNum = lockNum.replaceAll(regex,"$1\\-");
        lockNum = lockNum.substring(0,lockNum.length() - 1);
        int i = 0;
        String sql = "SELECT lockNum from t_locks WHERE lockCode = ?";
        PreparedStatement pstmt;
        ResultSet rs;
        String name = "";
        try {
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1, lockNum);
            rs = pstmt.executeQuery();
            while(rs.next()){
                //每次循环，都取出一条记录
                name = rs.getString("lockNum");

            }
            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return name;
    }

}
